﻿using HamcoWcs.Main.SingalRFiles;
using HamcoWcs.Models.QuartzModels;
using HamcoWcs.Workers;
using HamcoWcs.Workers.AmountWorkers;
using HamcoWcs.Workers.LoggerWorkers;
using HamcoWcs.Workers.MainTaskWokers;
using HamcoWcs.Workers.MESWokers;
using HamcoWcs.Workers.PconWorkers;
using HamcoWcs.Workers.RouteWorkers;
using HamcoWcs.Workers.SrmWorkers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace HamcoWcs.Main.Quartzs
{
    public class QuartzHostedService : IHostedService
    {
        /// <summary>
        /// 获取定时任务计划
        /// </summary>
        /// <returns></returns>
        private List<JobSchedule> GetJobSchedules() =>
            new()
            {
                //每天执行一次  任务统计
                new JobSchedule(typeof(ChartWorker), "", "0 0 0 1/1 * ?"),
                new JobSchedule(typeof(PconWorker), "Pcon01","0/1 * * * * ?"),
                new JobSchedule(typeof(PpkSrmWorker),"CJSTW100","0/1 * * * * ?"),
                new JobSchedule(typeof(PpkSrmWorker),"CJSTW200","0/1 * * * * ?"),
                // Lcd 定时服务
                new JobSchedule(typeof(LcdWorker),"Lcd","0/1 * * * * ?"),
                
                //new JobSchedule(typeof(GlobalMonitorWorker), "GlobalMonitorWorker", "0/1 * * * * ?"),


                new JobSchedule(typeof(MainTaskWoker), "MainTaskWoker", "0/1 * * * * ?"),
                new JobSchedule(typeof(MesWorker), "MesWorker","0/1 * * * * ?"),
                new JobSchedule(typeof(MonitorWorker), "MonitorWorker", "0/1 * * * * ?"),

                new JobSchedule(typeof(RouteWorker), "RouteWorker", "0/1 * * * * ?"),
                //new JobSchedule(typeof(TaskBakWork), "TaskBakWork", "0/1 * * * * ?"),

                // 每天删除一次过期日志
                //new JobSchedule(typeof(LoggerWorker), "Delete", "0/1 * * * * ?"),
                new JobSchedule(typeof(LoggerWorker), "Delete", "0 0 0 1/1 * ?"),
                //new JobSchedule(typeof(LoggerWorker), "MonitorWorker", "0/1 * * * * ?"),
                
                new JobSchedule(typeof(FileLogWorker), "FileLogWorker", "0/10 * * * * ?"),

                // 里程每天1点统计
                new JobSchedule(typeof(MilageWipWorker), "MilageWipWorker", "0 0 1 1/1 * ?"),

                // 每五秒监控网络
                new JobSchedule(typeof(NetWorker), "NetWorker", "0/5 * * * * ?"),

                
                // 60秒获取一次MES计划数
                new JobSchedule(typeof(GetStockerPlanWorker), "GetStockerPlanWorker", "0 0/1 * * * ?"),
                // 每小时获取读码率
                new JobSchedule(typeof(ReadRateWorker), "flag", "0 0 0/1 * * ?"),
                //new JobSchedule(typeof(ReadRateWorker), "flag", "0 0/1 * * * ?"),
                new JobSchedule(typeof(ReadRateWorker), "queue", "0 0/5 * * * ?"),

                //new JobSchedule(typeof(InterLockWorker), "InterLockWorker"),

#if DEBUG
#else
                new JobSchedule(typeof(TibcoMonitorWorker), "TibcoMonitorWorker", "0/1 * * * * ?"),
                new JobSchedule(typeof(InterLockWorker), "InterLockWorker"),
#endif
            };


        private readonly ISchedulerFactory _schedulerFactory;
        private readonly IJobFactory _jobFactory;
        private readonly IConfiguration _configuration;

        private List<JobSchedule> _jobSchedules = new List<JobSchedule>();
        private IScheduler _scheduler;
        public QuartzHostedService(
            ISchedulerFactory schedulerFactory,
            IJobFactory jobFactory, IConfiguration configuration)
        {
            _schedulerFactory = schedulerFactory;
            _jobFactory = jobFactory;
            _configuration = configuration;
        }
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            _scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
            _scheduler.JobFactory = _jobFactory;
            _jobSchedules = GetJobSchedules();
            foreach (var jobSchedule in _jobSchedules)
            {
                var job = CreateJob(jobSchedule);
                var trigger = CreateTrigger(jobSchedule);
                await _scheduler.ScheduleJob(job, trigger, cancellationToken);
            }
            await _scheduler.Start(cancellationToken);

        }


        public async Task StopAsync(CancellationToken cancellationToken)
        {
            await _scheduler.Shutdown(cancellationToken);
        }

        private ITrigger CreateTrigger(JobSchedule schedule)
        {
            var trigger = TriggerBuilder.Create()
                                        .WithIdentity($"{schedule.JobType.FullName}.{schedule.EqptSymbol}.trigger")
                                        .WithDescription($"{schedule.EqptSymbol}");

            if (!string.IsNullOrEmpty(schedule.CronExpression))
            {
                trigger = trigger.WithCronSchedule(schedule.CronExpression);
            }
            else
            {
                double cycleTime = 200;
                trigger = trigger.WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromMilliseconds(cycleTime)).RepeatForever());
            }

            return trigger.Build();
        }

        private IJobDetail CreateJob(JobSchedule schedule)
        {
            var jobType = schedule.JobType;
            return JobBuilder
                .Create(jobType)
                .WithIdentity($"{jobType.Name}.{schedule.EqptSymbol}")
                .WithDescription($"{jobType.Name}.{schedule.EqptSymbol}")
                .UsingJobData("eqptSymbol", schedule.EqptSymbol)
                .Build();
        }
    }
}
